﻿using Comm100.Framework.Domain.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bot.Domain.Entities;
using Bot.Domain.Interfaces;
using Bot.Domain.Bo;
using Castle.Windsor;
using Bot.Domain.Specifications;
using AutoMapper;
using Newtonsoft.Json;

namespace Bot.Domain.Categories.Service
{
    public class ResponseDomainService : IResponseDomainService
    {
        private IWindsorContainer _container;
        private readonly IRepository<Guid, Response> _repository;
        public IMapper Mapper { get; set; }

        public ResponseDomainService(IRepository<Guid, Response> repository, IWindsorContainer container)
        {
            this._repository = repository;
            this._container = container;
        }

        public Response Create(Response response)
        {
            if (response.Id == Guid.Empty)
            {
                response.Id = Guid.NewGuid();
            }
            //var result = _repository.Create(response);
            response.IsDeleted = false;
            if (response.Type == Enum.EnumAnswerType.image && response.Image != null)
            {
                response.ImageId = response.Image.Id;  
                //IImageDomainService imageDomainService = _container.Resolve<IImageDomainService>();
                //imageDomainService.Create(response.Image);
            }
            if (response.Type == Enum.EnumAnswerType.quickReply && response.QuickReply != null)
            {
                if (response.QuickReply.Id != Guid.Empty)
                {
                    response.QuickReplyId = response.QuickReply.Id;
                }
                else
                {
                    IQuickReplyDomainService quickReplyDomainService = _container.Resolve<IQuickReplyDomainService>();
                    var q = quickReplyDomainService.Create(response.QuickReply);
                    response.QuickReplyId = q.Id;
                }
            }
            if (response.Type == Enum.EnumAnswerType.webhook && response.Webhook != null)
            {
                IWebhookDomainService webhookDomainService = _container.Resolve<IWebhookDomainService>();
                var w = webhookDomainService.Create(response.Webhook);               
                response.WebhookId = w.Id;
            }
            var result = _repository.Create(response);
            if (response.Type == Enum.EnumAnswerType.button && response.Buttons != null && response.Buttons.Count > 0)
            {
                IResponseButtonDomainService responseButtonDomainService = _container.Resolve<IResponseButtonDomainService>();
                foreach(var button in response.Buttons)
                {
                    button.Id = Guid.NewGuid();
                    button.ResponseId = result.Id;
                    responseButtonDomainService.Create(button);
                }
            }
            return GetById(result.Id, "");
        }
        public Response Get(Guid id)
        {
            return _repository.Get(id);
        }
        public Response GetById(Guid id, string include)
        {
            var result = _repository.Get(id);
            if (result != null)
            {
                IImageDomainService imageDomainService = _container.Resolve<IImageDomainService>();
                IQuickReplyDomainService quickReplyDomainService = _container.Resolve<IQuickReplyDomainService>();
                IWebhookDomainService webhookDomainService = _container.Resolve<IWebhookDomainService>();
                IResponseButtonDomainService responseButtonDomainService = _container.Resolve<IResponseButtonDomainService>();


                if (result.Type == Enum.EnumAnswerType.image && result.ImageId.HasValue && result.ImageId != Guid.Empty)
                {
                    result.Image = imageDomainService.Get(result.ImageId.Value);
                }
                if (result.Type == Enum.EnumAnswerType.quickReply && result.QuickReplyId.HasValue && result.QuickReplyId != Guid.Empty)
                {
                    result.QuickReply = quickReplyDomainService.GetById(result.QuickReplyId.Value, include);
                }
                if (result.Type == Enum.EnumAnswerType.webhook && result.WebhookId.HasValue && result.WebhookId != Guid.Empty)
                {
                    result.Webhook = webhookDomainService.Get(result.WebhookId.Value);
                }
                if (result.Type == Enum.EnumAnswerType.button)
                {
                    result.Buttons = responseButtonDomainService.GetByResponseId(result.Id, include).ToList();
                }
            }
            return result;
        }

        public Response Update(ResponseUpdateBo bo)
        {
            if (bo.Type == Enum.EnumAnswerType.image && bo.Image != null)
            {
                bo.ImageId = bo.Image.Id;
                //IImageDomainService imageDomainService = _container.Resolve<IImageDomainService>();
                //imageDomainService.Create(response.Image);
            }
            if (bo.Type == Enum.EnumAnswerType.quickReply && bo.QuickReply != null)
            {
                if (bo.QuickReply.Id != Guid.Empty)
                {
                    bo.QuickReplyId = bo.QuickReply.Id;
                }
                else
                {
                    IQuickReplyDomainService quickReplyDomainService = _container.Resolve<IQuickReplyDomainService>();
                    //新增
                    QuickReply quickReply = Mapper.Map<QuickReply>(bo.QuickReply);
                    quickReply.Id = Guid.NewGuid();
                    quickReply.Type = Enum.EnumReplyType.custom;
                    quickReply.BotId = bo.QuickReply.BotId;                    

                    var q = quickReplyDomainService.Create(quickReply);
                    bo.QuickReplyId = q.Id;
                }
            }
            if (bo.Type == Enum.EnumAnswerType.webhook && bo.Webhook != null)
            {
                IWebhookDomainService webhookDomainService = _container.Resolve<IWebhookDomainService>();
                if (bo.Webhook.Id != Guid.Empty)
                {
                    bo.WebhookId = bo.Webhook.Id;
                    webhookDomainService.Update(bo.Webhook);
                }
                else
                {
                    //新增
                    Webhook webhook = Mapper.Map<Webhook>(bo.Webhook);
                    webhook.Id = Guid.NewGuid();                    
                    var w = webhookDomainService.Create(webhook);
                    bo.WebhookId = w.Id;
                }
            }
            //var result = _repository.Create(bo);

            if (bo.Type == Enum.EnumAnswerType.button && bo.Buttons != null && bo.Buttons.Count > 0)
            {
                IResponseButtonDomainService responseButtonDomainService = _container.Resolve<IResponseButtonDomainService>();
                List<Guid> buttonIds = new List<Guid> { };

                foreach (var item in bo.Buttons)
                {
                    if (item.Id != Guid.Empty)
                    {
                        //修改      
                        item.ResponseId = bo.Id;
                        responseButtonDomainService.Update(item);
                        buttonIds.Add(item.Id);
                    }
                    else
                    {
                        //新增
                        ResponseButton button = Mapper.Map<ResponseButton>(item);
                        button.Id = Guid.NewGuid();
                        button.ResponseId = bo.Id;                                              
                        responseButtonDomainService.Create(button);
                        buttonIds.Add(button.Id);
                    }
                }
                //删除
                var buttonItems = responseButtonDomainService.GetByResponseId(bo.Id);
                foreach (var q in buttonItems)
                {
                    if (!buttonIds.Contains(q.Id))
                    {
                        responseButtonDomainService.Delete(q.Id);
                    }
                }                
            }

            Response response = _repository.Get(bo.Id);
            //response.Id = bo.Id;
            //response.ParentId = bo.ParentId;
            response.Type = bo.Type;
            response.TextVariants = JsonConvert.SerializeObject(bo.TextVariants);
            response.HtmlTextVariants = JsonConvert.SerializeObject(bo.HtmlTextVariants);
            response.Message = bo.Message;
            response.ImageId = bo.ImageId;
            response.VideoUrl = bo.VideoUrl;
            response.QuickReplyId = bo.QuickReplyId;
            response.WebhookId = bo.WebhookId;
            response.Order = bo.Order;

            _repository.Update(response);

            return GetById(bo.Id, "");
        }

        public void Delete(Guid id)
        {
            Response response = _repository.Get(id);

            _repository.Delete(response);

        }

        public IEnumerable<Response> GetByParentId(Guid parentId, string include = "")
        {
            var list = _repository.List(new ResponseFilterSpecification(parentId)).ToList();
            if(list!=null&& list.Count > 0)
            {
                IImageDomainService imageDomainService = _container.Resolve<IImageDomainService>();
                IQuickReplyDomainService quickReplyDomainService = _container.Resolve<IQuickReplyDomainService>();
                IWebhookDomainService webhookDomainService = _container.Resolve<IWebhookDomainService>();
                IResponseButtonDomainService responseButtonDomainService = _container.Resolve<IResponseButtonDomainService>();

                foreach (var item in list)
                {
                    if(item.Type == Enum.EnumAnswerType.image && item.ImageId.HasValue && item.ImageId != Guid.Empty)
                    {
                        item.Image = imageDomainService.Get(item.ImageId.Value);
                    }
                    if(item.Type == Enum.EnumAnswerType.quickReply && item.QuickReplyId.HasValue && item.QuickReplyId != Guid.Empty)
                    {
                        item.QuickReply = quickReplyDomainService.GetById(item.QuickReplyId.Value, include);
                    }
                    if(item.Type == Enum.EnumAnswerType.webhook && item.WebhookId.HasValue && item.WebhookId != Guid.Empty)
                    {
                        item.Webhook = webhookDomainService.Get(item.WebhookId.Value);
                    }
                    if(item.Type == Enum.EnumAnswerType.button)
                    {
                        item.Buttons = responseButtonDomainService.GetByResponseId(item.Id, include).ToList();
                    }
                }
            }
            return list;
        }
        public IEnumerable<Response> GetByParentIds(List<Guid> parentIds, string include = "")
        {
            if(parentIds!=null &&
                parentIds.Count > 0)
            {
                var responseList = new List<Response>();
                foreach(var parentId in parentIds)
                {
                    responseList.Concat(GetByParentId(parentId, include));
                }

                return responseList;
            }

            return null;
        }
    }
}
